from Cheetah.Template import Template
from ConfigParser import RawConfigParser
import cobbler.utils
import cobbler.api as capi
import pprint


class GenConfig:

    def __init__(self,hostname):
        self.hostname    = hostname
        self.handle      = capi.BootAPI()
        self.system      = self.handle.find_system(hostname=self.hostname)
        self.mgmtclasses = self.get_host_mgmtclasses()
        self.resources   = self.get_resources()

    def get_host_vars(self):
        handle = self.handle
        system = self.system

        return cobbler.utils.blender(handle, False, system)['ks_meta']

    def get_host_mgmtclasses(self):
        handle = self.handle
        system = self.system

        return cobbler.utils.blender(handle, False, system)['mgmt_classes']

    def get_repositories(self):
        return self.resources['repositories']
    def get_groups(self):
        return self.resources['groups']
    def get_users(self):
        return self.resources['users']
    def get_mounts(self):
        return self.resources['mounts']
    def get_packages(self):
        return self.resources['packages']
    def get_files(self):
        return self.resources['files']
    def get_services(self):
        return self.resources['services']

    def get_resources(self):
        handle = self.handle
        mgmtclasses = self.mgmtclasses

        repository_list  = []
        group_list       = []
        user_list        = []
        mount_list       = []
        package_list     = []
        file_list        = []
        service_list     = []

        resources = {
            'repositories' : repository_list,
            'groups'       : group_list,
            'users'        : user_list,
            'mounts'       : mount_list,
            'packages'     : package_list,
            'files'        : file_list,
            'services'     : service_list,
        }

        # Construct the resources dictionary
        for mgmtclass in mgmtclasses:
            _mgmtclass = handle.find_mgmtclass(name=mgmtclass)

            for repo in _mgmtclass.repositories:
                repository_list.append(repo)
            for group in _mgmtclass.groups:
                group_list.append(group)
            for user in _mgmtclass.users:
                user_list.append(user)
            for mount in _mgmtclass.mounts:
                mount_list.append(mount)
            for package in _mgmtclass.packages:
                package_list.append(package)
            for file in _mgmtclass.files:
                file_list.append(file)
            for service in _mgmtclass.services:
                service_list.append(service)

        return resources

    def gen_repository_data(self):
        """
        Generate repository resources dictionary for use in configuration template
        """
        repository_resources = RawConfigParser()
        repository_resources.read('/etc/cobbler/resources/repositories')
        repository_list = self.get_repositories()
        repository_data = {}

        for repo in repository_list:
            options = repository_resources.options(repo)
            repository_data[repo] = dict([(k, repository_resources.get(repo, k)) for k in options])
            repo_data = {}
            repo_data['repo'] = repo
            repo_data['repodata'] = repository_data[repo]
            # Use options to fill in default repo.template
            t = Template(file='/etc/cobbler/repo.template', searchList=[repo_data])
            # Remove options from repository data, we only need the content + path
            repository_data[repo] = {}
            repository_data[repo]['content'] = t.respond()
            repository_data[repo]['path'] = '/etc/yum.repos.d/%s.repo' % repo

        return repository_data

    def gen_group_data(self):
        """
        Generate group resources dictionary for use in configuration template
        """
        group_resources = RawConfigParser()
        group_resources.read('/etc/cobbler/resources/groups')
        group_list = self.get_groups()
        group_data = {}

        for group in group_list:
            options = group_resources.options(group)
            group_data[group] = dict([(k, group_resources.get(group, k)) for k in options])

        return group_data

    def gen_user_data(self):
        """
        Generate user resources dictionary for use in configuration template
        """
        user_resources = RawConfigParser()
        user_resources.read('/etc/cobbler/resources/users')
        user_list = self.get_users()
        user_data = {}

        for user in user_list:
            options = user_resources.options(user)
            user_data[user] = dict([(k, user_resources.get(user, k)) for k in options])

        return user_data

    def gen_mount_data(self):
        """
        Generate mount resources dictionary for use in configuration template
        """
        mount_resources = RawConfigParser()
        mount_resources.read('/etc/cobbler/resources/mounts')
        mount_list = self.get_mounts()
        mount_data = {}

        for mount in mount_list:
            options = mount_resources.options(mount)
            mount_data[mount] = dict([(k, mount_resources.get(mount, k)) for k in options])

        return mount_data

    def gen_package_data(self):
        """
        Generate package resources dictionary for use in default configuration
        template.
        """
        package_resources = RawConfigParser()
        package_resources.read('/etc/cobbler/resources/packages')
        package_list = self.get_packages()
        pkg_data = {}

        for package in package_list:
            options = package_resources.options(package)
            pkg_data[package] = dict([(k, package_resources.get(package, k)) for k in options])
            pkg_data[package]['name'] = package

        return pkg_data

    def gen_file_data(self):
        """
        Generate file resources dictionary for use in configuration template
        """
        file_resources = RawConfigParser()
        file_resources.read('/etc/cobbler/resources/files')
        file_list = self.get_files()
        file_data = {}

        for file in file_list:
            options = file_resources.options(file)
            file_data[file] = dict([(k, file_resources.get(file, k)) for k in options])

            if 'template' in options:
                template_vars = self.get_host_vars()
                t = Template(file=file_data[file]['template'], searchList=[template_vars])
                file_data[file]['content'] = t.respond()
                del file_data[file]['template']

        return file_data

    def gen_service_data(self):
        """
        Generate service resources dictionary for use in configuration template
        """
        service_resources = RawConfigParser()
        service_resources.read('/etc/cobbler/resources/services')
        service_list = self.get_services()
        service_data = {}
        weighted_list = []

        for service in service_list:
            options = service_resources.options(service)
            service_data[service] = dict([(k, service_resources.get(service, k)) for k in options])

        for service in service_data:
            weighted_list.append({'name': service, 'weight': service_data[service]['weight']})

        return weighted_list

    def gen_config_data(self):
        """
        Generate Python configuration script.
        """
        config_data = {
            'repositories': self.gen_repository_data(),
            'groups': self.gen_group_data(),
            'users': self.gen_user_data(),
            'mounts': self.gen_mount_data(),
            'packages': self.gen_package_data(),
            'files': self.gen_file_data(),
            'services': self.gen_service_data(),
        }

        return config_data

    def gen_config_data_for_koan(self):
        """
        Return json object for Koan
        """
        import simplejson as json
        json_config_data = json.JSONEncoder(sort_keys=True, indent=4).encode(self.gen_config_data())

        return json_config_data
